﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows.Threading;
using Microsoft.DirectX.DirectSound;
using System.Collections;
using System.Windows.Controls;
using System.Data.SqlClient;
using System.Windows;
using System.IO;
using System.Management;
using System.Threading;

namespace SoundServant
{
    static public class SS
    {

        public static DispatcherTimer TenthOfASecondTimer;
        public static DispatcherTimer OneSecondTimer;

        public static string VersionName = "Melchizedek";
        private static bool fullScreenMode = true;

        public delegate void FullScreenModeChangedDelegate(bool fullScreenModeEnabled);
        public static event FullScreenModeChangedDelegate FullScreenModeChanged;

        public static bool FullScreenMode
        {
            get
            {
                return fullScreenMode;
            }
            set
            {
                fullScreenMode = value;
                FullScreenModeChanged(fullScreenMode);
            }
        }

        static SS()
        {
            TenthOfASecondTimer = new DispatcherTimer();
            TenthOfASecondTimer.Interval = TimeSpan.FromMilliseconds(100);
            TenthOfASecondTimer.Start();

            OneSecondTimer = new DispatcherTimer();
            OneSecondTimer.Interval = TimeSpan.FromMilliseconds(1000);
            OneSecondTimer.Start();
        }

        public static string FullMeetingType(MeetingType type)
        {
            switch (type)
            {
                case MeetingType.SchoolServiceMeeting:
                    return "Theocratic Ministry School, Service Meeting";
                case MeetingType.TalkWatchtowerStudy:
                    return "Public Talk, Watchtower Study";
                case MeetingType.Special:
                    return "Special";
                case MeetingType.COVisit:
                    return "C.O. Visit";
                case MeetingType.Wedding:
                    return "Wedding";
                case MeetingType.Memorial:
                    return "Memorial";
                default:
                    break;
            }
            return "";
        }

        public static string AbbrMeetingType(MeetingType type)
        {
            switch (type)
            {
                case MeetingType.SchoolServiceMeeting:
                    return "BkTmsSm";
                case MeetingType.TalkWatchtowerStudy:
                    return "PtWt";
                case MeetingType.Special:
                    return "Sp";
                case MeetingType.COVisit:
                    return "Co";
                case MeetingType.Wedding:
                    return "Wd";
                case MeetingType.Memorial:
                    return "Mem";
                default:
                    break;
            }
            return "";
        }

        static bool administratorAuthenticated = false;
        public static bool AdministratorAuthenticated { get { return administratorAuthenticated; } set { administratorAuthenticated = value; } }

        public static string MakeSQLSafe(string field)
        {
            field = field.Replace("'", "''");
            return field;
        }
        public static string ParseTimeSpan(TimeSpan timeSpan)
        {
            return timeSpan.Hours.ToString("0") + ":" + timeSpan.Minutes.ToString("00") + ":" + timeSpan.Seconds.ToString("00");
        }

        public static void SelectAllTextBox(object sender)
        {
            TextBox tb = sender as TextBox;
            DispatcherTimer timer = new DispatcherTimer();
            timer.Interval = new TimeSpan(100);
            timer.Start();
            timer.Tick += (EventHandler)delegate(object obj, EventArgs args)
            {
                tb.SelectAll();
                timer.Stop();
            };
        }

        public static void CleanLogs()
        {

        }

        public static void Clean()
        {
            Logs.Information("Cleaner", "Commencing clean");
            SqlConnection connection = SS.Connection();
            SqlCommand command;

            Logs.Information("Cleaner", "Checking HDD Space");
            while (true)
            {
                ManagementObject diskSpace = new ManagementObject("win32_logicaldisk.deviceid=\"c:\"");
                diskSpace.Get();
                ulong diskFree = (ulong)diskSpace["FreeSpace"];

                if (diskFree > (ulong)Options.Default.LowSpaceCleanTrigger)
                {
                    Logs.Information("Cleaner", "Sufficient HDD space available");
                    break;
                }

                command = new SqlCommand("SELECT recId FROM recordings ORDER BY recId ASC", connection);
                try
                {
                    int recordingToDelete = (int)(command.ExecuteScalar());

                    Logs.Information("Cleaner", "Deleting recording " + recordingToDelete);

                    string sql = "";
                    sql += " DELETE FROM recordings WHERE recId = " + recordingToDelete;
                    sql += " DELETE FROM discs WHERE discRec = " + recordingToDelete;
                    sql += " DELETE FROM tracks WHERE trackRec = " + recordingToDelete;

                    command = new SqlCommand(sql, connection);
                    command.ExecuteNonQuery();

                    if(Directory.Exists(Options.Default.BaseDirectory + "\\" + Options.Default.RecordDirectory + "\\" + recordingToDelete))
                        Directory.Delete(Options.Default.BaseDirectory + "\\" + Options.Default.RecordDirectory + "\\" + recordingToDelete, true);
                }
                catch (Exception e)
                {
                    Logs.Error("Error", "An error was encountered while trying to delete old recordings to clear old space", e.ToString());
                    break;
                }
            }

            DirectoryInfo logDirectoryInfo = new DirectoryInfo(Options.Default.BaseDirectory + "\\" + Options.Default.LogDirectory);
            FileInfo[] logFiles = logDirectoryInfo.GetFiles("*.txt");

            if (logFiles.Length > Options.Default.LogCount)
            {
                Logs.Information("Cleaner", "Culling log files");
                int logFilesToDelete = logFiles.Length - Options.Default.LogCount;
                Logs.Information("Cleaner", logFilesToDelete + " log files need to be deleted");

                for (int i = 0; i < logFilesToDelete; i++)
                {
                    Logs.Information("Cleaner", "Deleting log file - File: " + logFiles[i].FullName);
                    logFiles[i].Delete();
                }
            }

            connection.Close();
            Logs.Information("Cleaner", "Finished clean");
        }

        static public DateTime BuildDate()
        {
            System.Version version = System.Reflection.Assembly.GetExecutingAssembly().GetName().Version;
            DateTime buildDate = new DateTime(2000, 1, 1);
            buildDate = buildDate.Add(new TimeSpan(version.Build, 0, 0, version.Revision * 2));
            if (DateTime.Now.IsDaylightSavingTime())
            {
                buildDate = buildDate.AddHours(1);
            }
            return buildDate;
        }

        static public string Version()
        {
            System.Version version = System.Reflection.Assembly.GetExecutingAssembly().GetName().Version;
            string result = version.Major + "." + version.Minor + "." + version.Build + " " + SS.VersionName;
            // result += " (" + version.Build + "." + version.Revision + ")";
            return result;
        }

        public static SqlConnection Connection()
        {
            SqlConnection conn = new SqlConnection(Options.Default.DataBaseConnectionString);
            conn.Open();
            return conn;
        }

        public static void CopyDirectory(DirectoryInfo _source, DirectoryInfo _destination)
        {
            if (_destination.Exists) _destination.Delete(true);
            _destination.Create();

            foreach (DirectoryInfo dir in _source.GetDirectories())
            {
                CopyDirectory(dir, new DirectoryInfo(_destination + "\\" + dir.Name));
            }

            foreach (FileInfo file in _source.GetFiles())
            {
                file.CopyTo(_destination.FullName + "\\" + file.Name, true);
            }
        }

        public static long DirectorySize(DirectoryInfo directory)
        {
            long size = 0;

            if (!directory.Exists)
                return 0;

            foreach (FileInfo file in directory.GetFiles())
            {
                size += file.Length;
            }
            foreach (DirectoryInfo subDirectory in directory.GetDirectories())
            {
                size += DirectorySize(subDirectory);
            }

            return size;
        }
    }
}
